<template>
  <view v-if="custom" class="video-wrap flex justify-center" :style="{ height }">
    <video
      id="myVideo"
      :object-fit="fullScreenStatus ? 'contain' : 'fill'"
      :src="src"
      :autoplay="autoplay"
      :loop="false"
      :controls="false"
      :show-fullscreen-btn="false"
      :show-progress="false"
      :enable-progress-gesture="false"
      :show-center-play-btn="false"
      :style="videoStyle"
      :initial-time="initialTime"
      @fullscreenchange="fullscreenchange"
      @ended="(e) => homeBannerVideoEnd(e, i)"
      @timeupdate="timeupdate"
      @play="isPlay = true"
      @pause="isPlay = false"
      @loadedmetadata="loadedmetadata"
    >
      <view class="position-absolute flex justify-center items-center box" :style="videoBox">
        <!-- 蒙版 实现单击、双击事件 -->
        <view
          class="position-absolute click-mask"
          :style="maskStyle"
          @touchstart="touchstart"
          @touchmove="touchmove"
          @touchend="touchend"
        ></view>
        <!-- 提示框 -->
        <view
          v-if="showToastStatus"
          class="p-20rpx rounded"
          style="background-color: rgb(0 0 0 / 30%)"
        >
          <text v-if="toast.type === 'progress'" class="text-white">
            {{ formatTime(currentTime) }}
          </text>
          <text v-else class="text-white">
            {{ toast.msg }}
          </text>
        </view>

        <!-- 全屏状态下 -->
        <!-- 顶部tab栏 -->
        <view
          v-if="showProgressStatus && fullScreenStatus"
          class="position-absolute video-bg-top fullscreen-tabbar left-0 right-0 top-0"
        >
          <view style="height: 44px" class="flex items-center w-full">
            <view class="video-btn text-white">
              <wd-icon name="arrow-left" size="22px" @click="fullOrExitScreen"></wd-icon>
            </view>
          </view>
        </view>
        <!-- 控制条    -->
        <view
          v-if="showProgressStatus && fullScreenStatus"
          class="video-bg-bottom position-absolute bottom-0 left-0 right-0 color-white"
          :style="{ bottom: `${bottom}px` }"
        >
          <view class="flex items-center" style="height: 44px">
            <view class="video-btn">
              <wd-icon v-if="!isPlay" name="play-circle" size="22px" @click="playOrPause"></wd-icon>
              <wd-icon v-else name="pause-circle" size="22px" @click="playOrPause"></wd-icon>
            </view>
            <view id="progressControl" class="flex-1" style="height: 100%">
              <video-slider
                :duration="duration"
                :current-time="currentTime"
                :progress-width="progressWidth"
                :progress-left="progressLeft"
                :dot-width="dotWidth"
                @change="changeSlider"
                @update="updateSlider"
              />
            </view>
            <view
              class="flex justify-center items-center shrink-0"
              :style="{ width: hasHour ? '120px' : '80px' }"
            >
              <text class="font-sm">{{ formatTime(currentTime) }}/{{ formatTime(duration) }}</text>
            </view>
            <view class="video-btn">
              <wd-icon name="fullscreen-exit" size="22px" @click="fullOrExitScreen"></wd-icon>
            </view>
          </view>
        </view>
      </view>
    </video>

    <!-- 非全屏 状态下 自定义controls -->
    <view
      v-if="showProgressStatus && !fullScreenStatus"
      class="video-bg-bottom position-absolute bottom-0 left-0 right-0 color-white"
    >
      <view class="flex items-center" style="height: 44px">
        <view class="video-btn shrink-0">
          <wd-icon v-if="!isPlay" name="play-circle" size="22px" @click="playOrPause"></wd-icon>
          <wd-icon v-else name="pause-circle" size="22px" @click="playOrPause"></wd-icon>
        </view>
        <view id="progressControl" class="flex-1" style="height: 100%">
          <video-slider
            :duration="duration"
            :current-time="currentTime"
            :progress-width="progressWidth"
            :progress-left="progressLeft"
            :dot-width="dotWidth"
            :is-disabled="isDisabled"
            @change="changeSlider"
            @update="updateSlider"
          />
        </view>
        <view
          class="flex justify-center items-center shrink-0"
          :style="{ width: hasHour ? '120px' : '80px' }"
        >
          <text class="font-sm">{{ formatTime(currentTime) }}/{{ formatTime(duration) }}</text>
        </view>
        <view class="video-btn shrink-0">
          <wd-icon name="fullsreen" size="22px" @click="fullOrExitScreen"></wd-icon>
        </view>
      </view>
    </view>
  </view>

  <view v-else class="video-wrap flex justify-center" :style="{ height }">
    <video
      id="myVideo"
      class="position-relative"
      :object-fit="fullScreenStatus ? 'contain' : 'fill'"
      :src="src"
      :autoplay="autoplay"
      :loop="false"
      :controls="true"
      :show-fullscreen-btn="true"
      :show-progress="true"
      :enable-progress-gesture="false"
      :show-center-play-btn="false"
      :initial-time="initialTime"
      @play="testPlay"
      @timeupdate="testTimeUpdate"
      @ended="(e) => homeBannerVideoEnd(e, i)"
      @loadedmetadata="loadedmetadata"
      @fullscreenchange="fullscreenchange"
    >
      <!-- 加个蒙层覆盖，使滚动条不能拖动 -->
      <cover-view
        v-if="isDisabled"
        class="mask-video"
        :style="{
          width: `${maskWidth}px`,
        }"
      ></cover-view>
    </video>
  </view>
</template>

<script setup>
import { getCurrentInstance, nextTick } from 'vue'
import VideoSlider from './components/slider.vue'

const props = defineProps({
  custom: {
    type: Boolean,
    default: true,
  },
  isDisabled: {
    type: Boolean,
    default: false,
  },
  src: {
    type: String,
    default: '',
  },
  height: {
    type: [String],
    default: '225px',
  },
  initialTime: {
    type: Number,
    default: 0,
  },
  autoplay: {
    type: Boolean,
    default: false,
  },
  initFullscreen: {
    type: Boolean,
    default: false,
  },
})

const emits = defineEmits(['end'])

const instance = getCurrentInstance()

const isPlay = ref(false) // 播放状态
const videoContext = ref(null)
const currentTime = ref(0)
const duration = ref(0)
const progressWidth = ref(0)
const progressLeft = ref(44) // 距离左边的距离
const hasHour = ref(false) // 是否有小时
const dotWidth = ref(15)
const fullScreenStatus = ref(false) // 是否是全屏
const showToastStatus = ref(false) // 显示提示
const toast = ref({
  type: 'msg',
  msg: '提示',
})
const showProgressStatus = ref(true) // 显示控制条以及上面按钮

const dbCount = ref(0)
const oldTouch = ref({})
const oldValue = ref({})
const touchType = ref(null) // 看是否有拖拽

const {
  windowWidth,
  windowHeight,
  safeAreaInsets: { bottom },
} = uni.getWindowInfo()

console.log('w', windowWidth, windowHeight)

const videoBox = computed(() => {
  return {
    width: fullScreenStatus.value ? windowHeight + 'px' : '100%',
    height: fullScreenStatus.value ? windowWidth + 'px' : '100%',
  }
})
const videoStyle = computed(() => {
  // if (fullScreenStatus.value) {
  //   nextTick(() => {
  //     return {
  //       width: windowHeight + 'px',
  //       height: windowWidth + 'px',
  //     }
  //   })
  // }
  return {
    width: fullScreenStatus.value ? windowHeight + 'px' : '100%',
    height: fullScreenStatus.value ? windowWidth + 'px' : '100%',
  }
})
const maskStyle = computed(() => {
  let _bottom = 44
  if (fullScreenStatus.value) {
    _bottom = bottom + 44
  }
  return {
    inset: `0 0 ${_bottom}px`,
  }
})

const getProgressWidth = () => {
  // const query = uni.createSelectorQuery().in(instance.proxy)

  // query
  //   .select('#progressControl')
  //   .boundingClientRect((data) => {
  //     console.log('d', data)
  //     progressWidth.value = data.width || 0
  //     progressLeft.value = data.left || 0
  //     if (progressWidth.value >= dotWidth.value) {
  //       // 减去小圆点的宽度 15
  //       progressWidth.value = progressWidth.value - dotWidth.value
  //     }
  //     console.log('progressLeft', progressLeft.value, progressWidth.value)
  //   })
  //   .exec()

  // 先写死，后续在改进
  if (fullScreenStatus.value) {
    if (hasHour.value) {
      progressWidth.value = windowHeight - 44 - 120 - 44 - 15
    } else {
      progressWidth.value = windowHeight - 44 - 80 - 44 - 15
    }
  } else {
    if (hasHour.value) {
      progressWidth.value = windowWidth - 44 - 120 - 44 - 15
    } else {
      progressWidth.value = windowWidth - 44 - 80 - 44 - 15
    }
  }
}

// 播放或暂停
const playOrPause = () => {
  showToast({
    msg: isPlay.value ? '暂停' : '播放',
  })
  console.log('vv', videoContext.value)
  if (isPlay.value) {
    videoContext.value.pause()
  } else {
    showProgress()
    videoContext.value.play()
  }
}

// 全屏或者退出全屏
const fullOrExitScreen = () => {
  console.log('e')
  if (fullScreenStatus.value) {
    // 退出全屏
    videoContext.value.exitFullScreen()
  } else {
    // 打开全屏
    videoContext.value.requestFullScreen()
  }
}

const fullscreenchange = (e) => {
  console.log('fullscreenchange', e)
  fullScreenStatus.value = e.detail.fullScreen

  if (props.custom) {
    getProgressWidth()

    // nextTick(() => {
    //   getProgressWidth()
    // })
  } else {
    if (e.detail.fullScreen) {
      maskWidth.value = windowHeight * 0.77
    } else {
      maskWidth.value = videoWidth.value * 0.77
    }
  }
}

const timeupdate = (e) => {
  if (!showToastStatus.value) {
    currentTime.value = e.detail.currentTime
  }
}

const loadedmetadata = (e) => {
  console.log('loadedmetadata', e)

  // if (props.initFullscreen) {
  //   videoContext.value.requestFullScreen()
  // }

  if (props.custom) {
    if (props.initialTime) {
      currentTime.value = props.initialTime
    }
    duration.value = e.detail.duration
    const hours = Math.floor(e.detail.duration / 3600)
    if (hours > 0) {
      hasHour.value = true
    }

    getProgressWidth()
  }
}

/**
 * 时间格式化
 */
const formatTime = (seconds) => {
  const hours = Math.floor(seconds / 3600)
  seconds %= 3600
  const minutes = Math.floor(seconds / 60)
  seconds %= 60
  let result = ''
  if (hours > 0) {
    result += `${hours.toString().padStart(2, '0')}:`
  }
  result += `${minutes.toString().padStart(2, '0')}:`
  seconds = Math.floor(seconds)
  result += seconds.toString().padStart(2, '0')
  return result
}

const homeBannerVideoEnd = (e, i) => {
  console.log('e', e, i)
  if (props.custom) {
    // 让currentTime = duration 防止自定义progress留白
    currentTime.value = duration.value
  }
  emits('end')
}

// 进度条移动完后
const changeSlider = (e) => {
  videoContext.value.seek(e)
  showToastStatus.value = false
  // 进行播放
  videoContext.value.play()
}

// 进度条move时候
const updateSlider = (e) => {
  showProgress()
  videoContext.value.pause()
  showToastStatus.value = true
  showToast({
    type: 'progress',
    autoClose: false,
  })
  currentTime.value = e
}

let showToastTimer = null
const showToast = (options) => {
  toast.value.type = options.type || 'msg'
  toast.value.msg = options.msg || '提示'
  showToastStatus.value = true
  if (options.autoClose !== false) {
    showToastTimer && clearTimeout(showToastTimer)
    showToastTimer = setTimeout(() => {
      showToastStatus.value = false
      showToastTimer = null
    }, 500)
  }
}

let progressTimer = null
// 显示控制条
const showProgress = () => {
  showProgressStatus.value = true
  progressTimer = progressTimer ? clearTimeout(progressTimer) : null
  progressTimer = setTimeout(() => {
    hideProgress()
    progressTimer = null
  }, 3000)
}
// 隐藏控制条
const hideProgress = () => {
  showProgressStatus.value = false
}

// 显示或隐藏控制条
const showOrHideProgress = () => {
  showProgressStatus.value ? hideProgress() : showProgress()
}

const touchstart = (e) => {
  if (props.isDisabled) return
  oldTouch.value = e.changedTouches[0]
  oldValue.value = {
    currentTime: currentTime.value,
  }
}

const touchmove = (e) => {
  if (props.isDisabled) {
    showProgress()
    return
  }
  const newTouch = e.changedTouches[0]
  if (!touchType.value) {
    touchType.value = Math.abs(newTouch.pageX - oldTouch.value.pageX) > 20 ? 'currentTime' : null
    // if (fullScreenStatus.value) {
    //   touchType.value = Math.abs(newTouch.pageY - oldTouch.value.pageY) > 20 ? 'currentTime' : null
    // } else {
    //   touchType.value = Math.abs(newTouch.pageX - oldTouch.value.pageX) > 20 ? 'currentTime' : null
    // }

    if (touchType.value === 'currentTime') {
      videoContext.value.pause()
    }
  } else if (touchType.value === 'currentTime') {
    showToast({
      type: 'progress',
      autoClose: false,
    })
    showProgress()
    // 表示拖拽进度
    let newCurrentTime = 0

    newCurrentTime =
      ((newTouch.pageX - oldTouch.value.pageX) / 250) * duration.value * 2 +
      oldValue.value.currentTime * 1
    // if (fullScreenStatus.value) {
    //   newCurrentTime =
    //     ((newTouch.pageY - oldTouch.value.pageY) / 250) * duration.value * 2 +
    //     oldValue.value.currentTime * 1
    // } else {
    //   newCurrentTime =
    //     ((newTouch.pageX - oldTouch.value.pageX) / 250) * duration.value * 2 +
    //     oldValue.value.currentTime * 1
    // }
    newCurrentTime = newCurrentTime > duration.value ? duration.value : newCurrentTime
    newCurrentTime = newCurrentTime < 0 ? 0 : newCurrentTime

    currentTime.value = newCurrentTime
  }
}

const touchend = () => {
  if (touchType.value === 'currentTime') {
    videoContext.value.seek(currentTime.value)
    videoContext.value.play()
  } else {
    if (dbCount.value === 0 || dbCount.value === 1) {
      dbCount.value++
    }
    if (dbCount.value > 0) {
      setTimeout(() => {
        if (dbCount.value === 1) {
          // 单击
          showOrHideProgress()
        }
        if (dbCount.value === 2) {
          // 双击
          playOrPause()
        }

        dbCount.value = 0
      }, 250)
    }
  }
  touchType.value = null
  showToastStatus.value = false
}

/** ********** 没有自定义 start **********/
const startTime = ref(0)
const isPlaying = ref(false)
const watchTime = ref(0)
const maskWidth = ref(0)
const videoWidth = ref(0)
const testPlay = () => {
  if (props.isDisabled) {
    startTime.value = Date.now()
    isPlaying.value = true
  }
}
const testTimeUpdate = (event) => {
  if (props.isDisabled) {
    if (isPlaying.value) {
      const currentTime = event.detail.currentTime
      const elapsedTime = (Date.now() - startTime.value) / 1000
      if (currentTime > elapsedTime + 1 || currentTime < elapsedTime - 1) {
        videoContext.value.seek(elapsedTime)
        watchTime.value = currentTime
      }
    } else {
      videoContext.value.seek(watchTime.value)
    }
  }
}

const getVideoWidth = () => {
  uni
    .createSelectorQuery()
    .in(instance.proxy)
    .select('#myVideo')
    .boundingClientRect((data) => {
      console.log('d1', data)
      videoWidth.value = data.width
      maskWidth.value = data.width * 0.77
    })
    .exec()
}

/** ********** 没有自定义 end **********/

const openFullScreen = () => {
  console.log('openFullScreen', openFullScreen)
  videoContext.value.requestFullScreen()
}

onMounted(() => {
  console.log('onMounted')
  // #ifndef MP-ALIPAY
  videoContext.value = uni.createVideoContext('myVideo', instance)
  console.log('videoContent', videoContext.value)

  console.log('initFullscreen', props.initFullscreen)

  if (props.initFullscreen) {
    nextTick(() => {
      console.log('nextTick')
      openFullScreen()
    })
  }

  // #endif

  if (props.custom) {
    getProgressWidth()
    showProgress()
  } else {
    getVideoWidth()
  }
})

defineExpose({
  openFullScreen,
})
</script>

<style lang="scss" scoped>
.video-btn {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
}

.video-bg-top,
.video-bg-bottom {
  background-image: linear-gradient(to bottom, rgb(0 0 0 / 0%), rgb(0 0 0 / 50%));
}

.font-sm {
  font-size: $uni-font-size-sm;
}

.video-wrap {
  position: relative;
  width: 100%;

  // height: 225px;

  video {
    width: 100%;
    height: 100%;
  }
}

.box {
  left: 50%;
  transform: translateX(-50%);
}

.click-mask {
  inset: 0 0 44px;
}

.mask-video {
  position: absolute;
  bottom: 0;
  left: 50%;
  z-index: 999;
  width: 77%;
  height: 100rpx;
  content: '';
  transform: translateX(-50%);
}
</style>
